//观察者模式，它定义了一种一对多的关系，让多个观察者对象同事监听某一个主题对象，这个主题对象的
//状态发生变化时就会通知所有的观察者对象，使得他们能够自动更新自己。

//观察目标接口
interface Subject {
  addObserver: (observer: Observer) => void;
  deleteObserver: (observer: Observer) => void;
  notifyObservers: () => void;
}

//观察者接口
interface Observer {
  notify: () => void;
}
//具体观察目标类
class ConcreteSubject implements Subject {
  private observers: Observer[] = [];

  //添加观察者
  public addObserver(observer: Observer): void {
    console.log(observer + "is pushed");
    this.observers.push(observer);
  }

  //移除观察者
  public deleteObserver(observer: Observer): void {
    console.log(observer + "have deleted");
    const idx: number = this.observers.indexOf(observer);
    idx && this.observers.splice(idx, 1);
  }

  //通知观察者
  public notifyObservers(): void {
    console.log("notify all the observers" + this.observers);
    this.observers.forEach((observer) => {
      observer.notify();
    });
  }
}

//具体观察类
class ConcreteObserver implements Observer {
  constructor(private name: string) {}

  notify(): void {
    console.log(`${this.name} has been notified`);
  }
}

function useObserver(): void {
  const subject: Subject = new ConcreteSubject();
  const Leo = new ConcreteObserver("Leo");
  const Robin = new ConcreteObserver("Robin");
  const Pual = new ConcreteObserver("Pual");
  const Lisa = new ConcreteObserver("Lisa");

  subject.addObserver(Leo);
  subject.addObserver(Robin);
  subject.addObserver(Pual);
  subject.addObserver(Lisa);
  subject.notifyObservers();

  subject.deleteObserver(Pual);
  subject.deleteObserver(Lisa);
  subject.notifyObservers();
}

useObserver();
